#ifndef xpack_eowz_bicrease_value
#define xpack_eowz_bicrease_value
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::eowz_bicrease_value::inc
#include"define/base_type.hpp"
#include"macro/xexport.hpp"
#include"instruction/count_of_set.hpp"
#pragma pop_macro("xuser")

namespace mixc::eowz_bicrease_value::origin{
    template<class item_t>
    struct bicrease_value{
    private:
        item_t m_data = item_t(-1);
    public:
        operator uxx(){
            // Abstract：
            // 将 m_data 分为三部分
            // 位于 mid 之上的高位零个数表示负值 negtive
            // 位于 mid 之下的低位零个数表示正值 positive
            // 正值和负值都是往中间将位设置成 0
            // m_data 所表示实际值等于 postive - negtive
            //  
            //                 mid
            //                 ||||
            // m_data  : msb 01111000 lsb
            //                |    |||
            //                |    positive
            //                |
            //                negtive
            // mid      : 4 表示有四个可用置位位
            auto mid            = inc::count_of_set(m_data);

            // m_data     : 0111_1000
            // m_data - 1 : 0111_0111
            // low_bits : 0000_1111
            // positive : inc::count_of_set(low_bits) - 1 = 4 - 1 = 3
            auto low_bits       = m_data ^ (m_data - 1);
            auto positive       = inc::count_of_set(low_bits) - 1;

            // 负数位数等于:  总位数 - 整数位数 - 中间未设置的位数
            auto negtive        = xbitsof(m_data) - positive - mid;
            return positive - negtive;
        }

        bstate_t increase(){
            // 当 mid 只有一位的时候，当前 m_data 不能再计数了
            if (auto mid = inc::count_of_set(m_data); mid == 1){
                return bstate_t::fail;
            }
            // m_data     : 0111_1000
            // m_data - 1 : 0111_0111
            // result     : 0111_0000
            else{
                m_data         &= m_data - 1;     // 清除最低位
                return bstate_t::success;
            }
        }

        bstate_t decrease(){
            // 当 mid 只有一位的时候，当前 m_data 不能再计数了
            if (auto mid = inc::count_of_set(m_data); mid == 1){
                return bstate_t::fail;
            }
            // m_data      : 0111_1000
            // m_data >> 1 : 0011_1100
            // result      : 0011_1000
            else{
                m_data         &= m_data >> 1;    // 清除最高置位位
                return bstate_t::success;
            }
        }
    };
}

#endif

xexport_spacex(eowz, mixc::eowz_bicrease_value::origin)
